<?php


/**
 * CF_class_com is the common include file for CF_class without DB functions
 *
 * CF_class_com is the common include file for CF_class.  It does not include DB specific functions, or helper functions
 * in the file, and contains a @package tag
 * @package CFtable
 */

 

/**
 *CFListAttributes was used for holding page specifc info.  Depreciated
 *
 * CFList Appls is not used anymore
 * @package CFtable
 * @author Md
 * @version 1.0
 * @abstract This is the abstract for thi
 * @copyright never
 */
class CFListAtts{
// Sort variables
	var $new_order;
	var $cur_order;
	var $pagename;
	var $new_dir;
	var $cur_dir;
	var $orderstring;
	var $ordervar = 'order';

//paging variables
	var $startat;
	var $numrows;
	var $post_rowlimit;
	var $startatvar = 'startat';
	var $numrowsvar = 'numrows';
	var $default_row_limit = 10;
	var $nextpagestart;
	var $prevpagestart;
	var $rowsmax = 1000000; // default 0 for unknown
	

}

include_once "CF_support.php";
// Classes
/**
 * BasicTable is a class to dumping of data from a database in an array.  This basic version makes an HTML output
* @package CFtable
 * @author Chris Tyler
 * @version 1.0
 * @BasicTable is the base class for the an extensable HTML table class for array based data.  This provides data display, sorting, filtering, paging and heading functions
 * @copyright 2007-2008 
 */
class BasicTable {
	/**
	* @var array $valuesarray A 2D array of values, an array of associative row arrays, valuesarray[<row number>][<column heading>]
	*/
	var $valuesarray;
	/**
	* @var array $fieldspec Array describes data and formatting options
	*/	
	var $fieldspec;
	
	var $row_status;
	
	var $show_all_rows;
	
	var $multiselect = false; // This is always false for basic Table, but is used to other functions can be expanded.
	
	
	function BasicTable( $the_spec = 'all', $values_array = ''){
		$this->values_array = $values_array;
		if(is_array($the_spec)){
			$this->fieldspec = $the_spec;
			$this->show_all_rows = false;
			}
		else{
			$this->show_all_rows = true;
			}
	}

	function set_valuesarray($dataarray){
		$this->valuesarray = $dataarray;	
	}	
	
/**
 * Set FieldSpec Function
 * @param array $thespec - The fieldspec array
 * @param array $thespec [<colname>] - Set for each column, as named in the database query used
 * @param array $thespec [<colname>] ['headname'] (opt) - Name to display on the header for the column.  If not there, will use <colname>
 * @param array $thespec [<colname>] [key] - If set (1), this will be used as a key field for record operations
 * @param array $thespec [<colname>] [show] - If set (1), this column will show in displays.  If 0 or unset, column will not appear
 * @param array $thespec [<colname>] [select] - How to display editable boxes: {T = Text Input, C = Check box (0 or 1), D = drop down) 
 * @param array $thespec [<colname>] [list] = array of values (showvalue, keyvalue) to use in drop-down.  Array is of form:  valueslist [<index integer>][<keyvariablename>][<showvariablename>] Where defaults are keyvariablename = 'keyvalue' showvariable='showvalue' unless re-assigned
  * @param array $thespec [<colname>] [showkey] - (opt)  Re-assignes the <keyvariablename> to the string specified, instead of 'keyvalue'
 * @param array $thespec [<colname>] [valuekey] - (opt) Re-assignes the <showvariablename> to the string specified, instead of 'showvalue'
 * @param array $thespec [<colname>] [sort] - Specifies if row header will sort or not, {true, false, (or undefined)}
 * @param array $thespec [<colname>] [filter] - Specifies if row is filtered. if set= 'keyword', then will  bet textbox for LIKE '%keyword%' search.  If set (= 1, but not specific setting ), then will filter using spec from edit criteria ([select],[list],)
 */		
	function set_fieldspec($thespec){
		$this->fieldspec = $thespec;
	}	
	
	function clear_keys_strings(){}
	
	function make_key_string($col_name, $currentvalue){}
	

/**
 * function to make start of row.  Override / extend
 * @param int $row_num This is the row number of the dataset
 * @param string $key_string This is the string of key values, defined by make_key_string function
 * @return string Row begining 
 */
	function make_row_start($row_num){
		if($this->row_status == 'even'){
			$this->row_status = 'odd';
			$rowstart .= "<tr class=\"even_row_color\">";			
		}
		else{
			$this->row_status = 'even';
			$rowstart .= "<tr class=\"odd_row_color\">";			
		}

		return $rowstart;
	}
	
	function make_row_end($row_num){
		return "</tr>\n";	
	}
	
	function make_rowval($currentvalue, $col_name, $current_text){
		return "<td>$currentvalue</td>";
	}
	
	function on_start_row($row_num){
	}

	
	/**
	 * maketable will return the table text from the class, for use as the body of a table
	 * @return string
	 */
	function maketable(){
		//print_r($this->fieldspec);
		if(!empty($this->valuesarray)){
		foreach($this->valuesarray as $row_num => $currentrow) {	
			$this->on_start_row($row_num);
			$this->clear_keys_strings();  // Clear keys_string
			$row_text = '';
			//$col_num = 0; // count column numbers incase of csv or difference in row_val function
			foreach ($currentrow as $col_name => $currentvalue) {
				
				
				if(!empty($this->fieldspec[$col_name]['key'])){
					$this->make_key_string($col_name, $currentvalue);
				}
				
				if($this->show_all_rows or (!empty($this->fieldspec[$col_name]['show']))){
					$row_text .= $this->make_rowval($currentvalue, $col_name, $row_text);

				}// end show field
			}// End for each column (value) in row
			$table_text .= $this->make_row_start($row_num) . $row_text . $this->make_row_end($row_num) ; 
		}// end for each row
		}// end is not empty valuesarray
		return $table_text;	
	
	}
	
	
} // End BasicTable Class

/**
 * csvTable is a class to output CSV from an array, usually returned form a Database
* @package CFtable
 * @author Chris Tyler
 * @version 1.0
 * @copyright 2007-2008 
 */
Class csvTable Extends BasicTable{

	var $is_first_col = true;

	function make_row_start($row_num){

	}
	/**
	 * make_row_end for CSV - insert line end, and reset first coumn bool
	 * @return string
	 */
	function make_row_end($row_num){
		$this->is_first_col = true; // carefull - that this is always run AFTER the rows are made!	
		return "\n";

	}
	/**
	 * make_rowval for CSV - escape the text properly, and only insert a , after the first value
	 * @return string
	 */	
	function make_rowval($currentvalue, $col_name, $current_text){
		if($this->is_first_col){
			$this->is_first_col = false;		
			return csvEscapeText($currentvalue);
			
			}
		else{
			return ',' . csvEscapeText($currentvalue);
			}
	}
	/**
	 * maketable will return the a heading line  (+ line return)  for the csv based on the fieldspec
	 * @return string
	 */		
	function make_heading(){
		if(!is_array($this->fieldspec)){
			return;
		}
		$after_first_col = false;
		if($this->multiselect){
			$headtext .= 'Select';
		}
		foreach($this->fieldspec AS $col_name => $colspec){
			if($after_first_col){
				$headtext .= ',';
				}// if after_first_col = true, then add the comma.  if it is false, then don't.
				
			if(empty($colspec['headname'])){
				$headtext .= csvEscapeText($col_name);
				}
			else{
				$headname = $colspec['headname'];
				$headtext .= csvEscapeText($headname);
				}
			$after_first_col = true;
			}
		return $headtext . "\n";

	}
	/**
	 * export_to_csv will export the csv as a file to the browser.  It will use the current fieldspec and values array.
	 *@param string filename - the full filename (with extension) to use when returning the data.
	 *@param use_heading - Set to true to include a heading (from make_heading) as the first line of the file
	 * @return string
	 */
	function export_to_csv($filename, $use_heading = false){
		if($this->valuesarray){
			if($use_heading){
				$heading = $this->make_heading();
			}
			$csv_file_text = $heading . $this->maketable();
			
			header("Content-type: application/x-msdownload");
			header("Content-Disposition: attachment; filename=$filename");
			header("Pragma: no-cache");
			header("Expires: 0");
			echo $headers.$csv_file_text;
		}
		else{
			echo 'There is no data avalible for this csv';
			}
	
	} // end export_to_csv


} // end Class csvTable







/**
 * CFtable is a class to simplfy creation of Databse CRUD (Create Remove Update Delete) Tables
* @package CFtable
 * @author Chris Tyler
 * @version 1.0
 * @CFtable is the base class for the an extensable HTML table class for array based data.  This provides data display, sorting, filtering, paging and heading functions
 * @copyright 2007-2008 
 */

class CFtable extends BasicTable{

	
	/**
	* @var string $table_name Defines name of the table (associated elements)
	*/	
	var $table_name = 'datatable';
	/**
	* @var string $table_start Defines start of the string for use in HTML data output.  (unused)
	*/
	var $table_start;
	/**
	* @var string $table_text String of HTML for output as table
	*/	
	var $table_text;
	/**
	* @var string $selfpage The name of the page, usualy set by $_SERVER['SELF']
	*/
	var $selfpage;
	/**
	* @var array $referstrng (not used)
	*/
	var $referstring;	
	// persistant info:  The ordervar, filtersvar, and liststartvar, listsizevar will hold the state of the ordering and filters
	// as shown on the page when the list is shown.
	// set this variable for order when re-ording this query with the headers

	//var $filtersvar = 'cfFilters'; // holds the string of all set filters, ready for append to url
	/**
	* @var string $liststartvar String used for list start variable
	*/	
	var $liststartvar = 'cfListStart'; 
	/**
	* @var string $liststartvar String used for list size variable
	*/		
	var $listsizevar = 'cfListSize';
	// set this variable to hold the filters string
	// prefix for filtered variables (column name used)
	/**
	* @var string $fprefix String used for list size variable
	*/
	var $fprefix = flt_;
	// Variables changed by functions
	var $row_status;	
	var $url_keys_string;
	var $addtype = 'button'; // button, keys, are options
	
	var $filters; // variable array for filters, filters[filter_name][variable] = <colname> , filters[filter_name][value] = setting, filters[filter_name][text] = filter
	var $filterprefix = 'flt_';
	var $multiselect = true;
	var $keys_uid;  // keys as semicolon (;) delimited fields per row

	
	
// Sort variables
	var $new_order;
	var $cur_order;
	var $pagename;
	var $new_dir;
	var $cur_dir;
	var $orderstring;
	var $ordervar = 'order';

//paging variables
	var $startat;
	var $numrows;
	var $post_rowlimit;
	var $startatvar = 'startat';
	var $numrowsvar = 'numrows';
	var $default_row_limit = 10;
	var $nextpagestart;
	var $prevpagestart;
	var $rowsmax = 1000000; // default 0 for unknown	
	var $oracle_post_rowlimit;
	var $oracle_pre_rowlimit = "SELECT * FROM ( SELECT thequery.*, rownum rnum from ( ";
	var $pgsql_post_rowlimit;
	var $fbird_fix_rowlimit;
	
	
/**
 * Constructor.  Override / extend
 * @param array $thespec - The fieldspec array
 * @param array $dataarray - The data array, data[<rownumber>][<column_name>]
 */		
	function CFtable( $thespec = '', $dataarray= '', $allowspec = 'rde' ){
		$this->fieldspec = $thespec;	
		$this->valuesarray = $dataarray;
		
		$this->selfpage = "listpage.php"; // set to $_SERVER['PHP_SELF'] in callin code
		$this->ordervar = 'order';	
		
	}
	


	
	function set_name($name){
		$this->table_name = $name;	
	}
	

	
	function set_valuesarray($dataarray){
		$this->valuesarray = $dataarray;	
	}	
	
/**
 * Set FieldSpec Function
 * @param array $thespec - The fieldspec array
 * @param array $thespec [<colname>] - Set for each column, as named in the database query used
 * @param array $thespec [<colname>] ['headname'] (opt) - Name to display on the header for the column.  If not there, will use <colname>
 * @param array $thespec [<colname>] [key] - If set (1), this will be used as a key field for record operations
 * @param array $thespec [<colname>] [show] - If set (1), this column will show in displays.  If 0 or unset, column will not appear
 * @param array $thespec [<colname>] [select] - How to display editable boxes: {T = Text Input, C = Check box (0 or 1), D = drop down) 
 * @param array $thespec [<colname>] [list] = array of values (showvalue, keyvalue) to use in drop-down.  Array is of form:  valueslist [<index integer>][<keyvariablename>][<showvariablename>] Where defaults are keyvariablename = 'keyvalue' showvariable='showvalue' unless re-assigned
  * @param array $thespec [<colname>] [showkey] - (opt)  Re-assignes the <keyvariablename> to the string specified, instead of 'keyvalue'
 * @param array $thespec [<colname>] [valuekey] - (opt) Re-assignes the <showvariablename> to the string specified, instead of 'showvalue'
 * @param array $thespec [<colname>] [sort] - Specifies if row header will sort or not, {true, false, (or undefined)}
 * @param array $thespec [<colname>] [filter] - Specifies if row is filtered. if set= 'keyword', then will  bet textbox for LIKE '%keyword%' search.  If set (= 1, but not specific setting ), then will filter using spec from edit criteria ([select],[list],)
 */		
	function set_fieldspec($thespec){
		$this->fieldspec = $thespec;
	}
	
	function set_ordervar($newordervar){
		$this->ordervar = $newordervar;
	}	
	
	function set_selfpage($newpage){
		$this->selfpage = $newpage;
	}
	
/**
 * function to make key string.  Override / extend
 * @param int $col_name This is the column name for the key value
 * @param string $currentvalue This is the value of the key
 * @param int $firstrow This is 1 for the first row, 0 afterwards for special punctuation
 * @return string keystring
 */	
	
		function make_key_string($col_name, $currentvalue, $firstrow = 0){
		if(empty($this->keys_uid)){
			$this->keys_uid =  "$currentvalue";
	
		}
		else{
			$this->keys_uid .=  ",$currentvalue";
		}
		//$this->url_keys_string .= "&$col_name=$currentvalue";
		$this->keys_hidden .= "<input type='hidden' name='$col_name' value='$currentvalue'>";
		//parent::make_key_string($col_name, $currentvalue);
		$this->url_keys_string .= "&$col_name=$currentvalue";
		
	}
	
	
//	function make_key_string($col_name, $currentvalue, $firstrow = 0){
//		$this->url_keys_string .= "&$col_name=$currentvalue";
//	}
	
/**
 * function to make start of row.  Override / extend
 * @param int $row_num This is the row number of the dataset
 * @param string $key_string This is the string of key values, defined by make_key_string function
 * @return string Row begining 
 */
	function make_row_start($row_num){
		if($this->row_status == 'even'){
			$this->row_status = 'odd';
			$rowstart .= "<tr class=\"even_row_color\">";			
		}
		else{
			$this->row_status = 'even';
			$rowstart .= "<tr class=\"odd_row_color\">";			
		}
		if($this->multiselect){
			$rowstart .= "<td>" . $this->make_multiselectCB() . "</td>";
		}	
		return $rowstart;
	}

	function make_multiselectCB(){
		return "<input type='checkbox' name='" . $this->table_name . "_addto_ms' value='" . $this->keys_uid . "' >";
	
	}	
	
	function make_row_end($row_num){
		return "</tr>\n";
	}
	
	function make_rowval($value,$column){
		$row_text .= "<td>";
		$row_text .= $value;
		$row_text .= "</td>";
		return $row_text;
			
	}

	function clear_keys_strings() { 
		$this->url_keys_string = '';
		$this->keys_uid = '';
	}
	


	/**
	 * make_simple_heading will return a heading row of the column name
	 * @return string
	 */	
	function make_simple_heading(){
	if($this->multiselect){
		$headtext .= '<th>Select</th>';
	}
	foreach($this->fieldspec AS $col_name => $colspec){
		$headtext .= '<th>';
		(empty($colspec['headname']))?$headtext .= $col_name: $headtext .= $colspec['headname'] . '</th>\n';
		}
	return $headtext;
	}

	/**
	 * make_sort_heading will return a heading where clicking on the colum name will sort by the column
	 * This requiresthe page to reload to sort the the column name through the variable specified by
	 * set_ordervar().  The return page is set in set_selfpage().
	 * @return string
	 */
	function make_sort_heading(){
	if($this->multiselect){
		$headtext .= '<th>Select</th>';
	}
	foreach($this->fieldspec AS $col_name => $colspec){
		if(!empty($colspec['show'])){
		$headtext .= '<th>';
		(empty($colspec['headname']))?$name = $col_name: $name = $colspec['headname'] . '</th>\n';
		
		if($colspec['sort'] == true){
			$headtext .= "<a href=\"$this->selfpage?$this->ordervar=$col_name$referstring\">$name</a>";
		}
		else{
			$headtext .= $name;
		}
		$headtext .= "</th>";
		} // end if shown
		}// end foreach
				
	return $headtext;
	}
	
	
	
	/**
	 * make_filter will make the filter input box
	 * according to the feildspec[<column>][filter] specs
	 * @param string $column - This is the column to make the field box for
	 * INCOMPLETE
	 */
	
	function make_filter($column){
				
			if($this->fieldspec[$column]['select'] == 'D'){
				$flttext = "<input type='text' name='$fprefix_$colname' value='{$colspec['default']}'>";
			}
			else{
				$flttext = "<input type='text' name='$fprefix_$colname' value='{$colspec['default']}'>";			
			}	
			return $flttext;	
		}
	

	function get_filter_vals(){
	//$_SESSION['Testthing']['lastthing'] = "Goodbye";	
		foreach($this->fieldspec AS $col_name => $colspec){
			if(!empty($colspec['filter'])){
			//print "Filter is " . $colspec['filter'];
				if($colspec['filter'] == 'keyword'){
					
				}
				else{
					//print "Look for Request " . $this->filterprefix . $col_name . "<br>";
					if(isset($_REQUEST[$this->filterprefix . $col_name]) AND $_REQUEST[$this->filterprefix . $col_name] != '' ){
					//print "Filter is identified fro request for $col_name";
						$this->filters[$this->filterprefix . $col_name]['var'] = $col_name;
						$this->filters[$this->filterprefix . $col_name]['val'] = $_REQUEST[$this->filterprefix . $col_name];
					
					}
					else if(!empty($_SESSION[$this->pagename]['filters'][$this->filterprefix . $col_name])){
						$this->filters[$this->filterprefix . $col_name]['var'] = $col_name;
						$this->filters[$this->filterprefix . $col_name]['val'] = $_SESSION[$this->pagename]['filters'][$this->filterprefix . $col_name];
					}
				}
			}
		}
	}
	
	/**
	 * make_query_filter will create a query filter according to fieldspec settings, Request input, and Session data
	 * INCOMPLETE
	 */
	function make_query_filter(){
		if(!empty( $this->filters)){
			foreach($this->filters AS $filtername => $filter){
				$flt_text .= " AND " . $filter['var'] . " = '" . $filter['val'] . "' ";

		}	
		}
	
	return $flt_text;
	}
		/**
		 * make_filter_box will make the filter input box of all filters
		 * according to the feildspec[<column>][filter] specs
		 * INCOMPLETE
		 */
	function make_filters_box($method = 'get'){
		$none_entry[1]['keyvalue'] = '';
		$none_entry[1]['showvalue'] = '';
	
		$filterbox .= "<table class='filterbox'><form action='$this->selfpage' method='$method'>";
		foreach($this->fieldspec AS $col_name => $colspec){
			
			if(!empty($colspec['filter'])){
				$filtername = $this->filterprefix . $col_name;
				$filterbox .= "<td>";
				$filterbox .= $col_name;
				$filterbox .= $this->make_editbox($col_name, $filtername, $this->filters[$filtername]['val'], '', $filtername, $none_entry);
				$filterbox .= "</td>\n";				
			}// end colpsec filter set
				
				
		}// end foreach field
		
		$filterbox .= "<tr><td> <input type='submit' name='refresh'></form> </td></tr>\n";
		
	return $filterbox;		
		
	} // end make_filter_box
	

	/**
	 * will make the  input box of all filters
	 * according to the feildspec[<column>][filter] specs
	 * @param string $column Column to make input element for
	 * @param string $elename Element Name 
	 * @param string $changefunction is onChange, onBlur or onClick function
	 * @param string $eleid = element id 
	 * @param string $noselect = text for first 'non selected' parameter.  if false ( default), it is left out.	 
	
	 */
	function make_editbox($column, $elename, $def_value = '', $changefunction = '', $eleid = '', $prelist = false){
		$rawformat = $this->fieldspec[$column]['rawformat'];
		// defaults for list key and value
		$showkey = 'showvalue';
		$valuekey = 'keyvalue';
		
		
		if($this->fieldspec[$column]['select'] == 'D'){
			$valuesarray = $this->fieldspec[$column]['list'];
			$showkey = $this->fieldspec[$column]['showkey'];
			$valuekey = $this->fieldspec[$column]['valuekey'];
			$dd_opts['id'] = $selectname; //  . '_' . $row_keys_string;
			//$dd_opts['onchangeparam'] = "$changefunction";
			$dd_opts['id'] = $eleid;
			$dd_opts['onchangename'] = $changefunction;
			
			$select_text = make_array_select($valuesarray, $elename, $showkey,$valuekey,$def_value, 40, $dd_opts, $prelist);
			$field .= "\n$select_text\n";	
			
	}//end if select type 'D'
		else if ($this->fieldspec[$column]['select'] == 'C'){
			if(!$prelist){ // if we dont need a thrid 'neither' option, then make a checkbox
				$field .= "<input type='hidden' name='$elename' value='0'>"; 
				// NOTE:  the above hidden  this does not have an id, only a name, so that the javascript will not catch it using by_id, but the form processing will (using name)
				if($def_value != 0){
					$field .= "<input type='checkbox' name='$elename' id='$eleid' value='1' CHECKED $rawformat onClick=\"$changefunction\">\n";
				}
				else {
					$field .= "<input type='checkbox' name='$elename' id='$eleid' value='1' $rawformat onClick=\"$changefunction\">\n";
				}			
			}// end no prelist
			else{
				$yesnoarray[1]['keyvalue'] = 0;
				$yesnoarray[1]['showvalue'] = 'No';
				$yesnoarray[2]['keyvalue'] = 1;
				$yesnoarray[2]['showvalue'] = 'Yes';
				
				$field = make_array_select($yesnoarray, $elename, 'keyvalue','showvalue',$def_value, 40, $dd_opts, $prelist);
				
			}
			
		}// end if checkbox type 'C'
		else if ($this->fieldspec[$column]['select'] == 'R'){
			$valuesarray = $this->fieldspec[$column]['list'];
			$showkey = $this->fieldspec[$column]['showkey'];
			$valuekey = $this->fieldspec[$column]['valuekey'];
			$dd_opts['id'] = $selectname; //  . '_' . $row_keys_string;
			//$dd_opts['onchangeparam'] = "$changefunction";
			$dd_opts['id'] = $eleid;
			$dd_opts['onchangename'] = $changefunction;
			
			$select_text = make_array_radiogroup($valuesarray, $elename, $showkey,$valuekey,$column, 40, $dd_opts, $noselect);
			$field .= "\n$select_text\n";	
			
	}// end if radiobutton
		else if($this->fieldspec[$column]['select'] == 'T'){
			if(!empty($changefunction)){
				$blurparam = "onBlur = \"$changefunction\"";	
			}
			$field .= "<input type='text' name='$elename' id='$eleid' value='$def_value' $rawformat $blurparam >\n";
		}
		
		return $field;
	}


	function make_add_box($type = 'button'){
		if($this->addtype == 'button'){
			$addform .= "<form name='$this->table_name" . "_Add' action='$this->actionpage' method='GET'>";
			$addform .= "<input type='submit' name='mode' value='Add'>";
			$addform .= "</form>";
		}
		if($this->addtype == 'keys'){
			$addform .= "<form name='$this->table_name" . "_Add' action='$this->actionpage' method='GET'>";
			foreach($this->fieldspec AS $col_name => $colspec){
				if((!empty($colspec['key'])) OR (!empty($colspec['add']))){
					$addform .= $col_name;
					$addform .= $this->make_editbox($col_name, $this->addprefix . $col_name);
					}
			}
			$addform .= "<input type='submit' name='mode' value='Add'>";
			$addform .= "</form>";
		}
		return $addform;
		
	}

	function get_sort_orders(){
		if(isset($_SESSION[$this->table_name . '_order']) AND $_SESSION[$this->table_name . '_order'] != ''){
			$this->cur_order = $_SESSION[$this->table_name . '_order'];
			$this->cur_dir = $_SESSION[$this->table_name . '_dir'];
			
			$this->orderstring = " ORDER BY $this->cur_order  $this->cur_dir "; 
			
			}
		if(isset($_REQUEST['order']) AND $_REQUEST['order'] != ''){
			$this->new_order = $_REQUEST['order'];
			if($this->new_order == $this->cur_order){ // flip direction if clicked twice
				if($this->cur_dir == 'DESC'){
					$this->cur_dir = 'ASC';
				}
				else{
					$this->cur_dir = 'DESC';
				}
			}// End same order clicked twice
			else{
				$this->cur_order = $this->new_order;
				$this->cur_dir = 'ASC'; // default to asc
			}
		$_SESSION[$this->table_name . '_order'] = $this->cur_order;
		$_SESSION[$this->table_name . '_dir'] = $this->cur_dir;
		
		$this->orderstring = " ORDER BY $this->cur_order  $this->cur_dir "; 
		
	
		} // end order in request
	} // end get sort order
	
	function make_query_sort(){
		$this->get_sort_orders();
		return $this->orderstring;
	
	}
	
	function get_pagination(){
	
		//paging
		if (!empty($_REQUEST[$this->numrowsvar])){
			$this->numrows =  $_REQUEST[$this->numrowsvar];
		}
		else if(isset($_SESSION[$this->table_name . '_numrows'])){
			$this->numrows =  $_SESSION[$this->table_name . '_numrows'];
		}
		else if ($this->default_row_limit != 0) {
			$this->numrows = $this->default_row_limit;
			}
		
		if (isset($_REQUEST[$this->startatvar])){
			$this->startat =  (int)$_REQUEST[$this->startatvar];
			$this->post_rowlimit = " LIMIT $this->startat , $this->numrows ";
			$this->oracle_post_rowlimit = " ) thequery <= " . $this->startat + $this->numrows;
			$this->oracle_post_rowlimit .= " ) where rnum >= $this->startat ORDER BY rnum ";
			$this->pgsql_post_rowlimit = " LIMIT $this->numrows OFFSET $this->startat ";
			$this->fbird_fix_rowlimit = " FIRST $this->numrows SKIP $this->startat ";
			
			
//print "JUST SET REQUEST startat:	$this->startat <br>";	
		}		
		else if(isset($_SESSION[$this->table_name . '_startat'])){
			$this->startat =  $_SESSION[$this->table_name . '_startat'];
			$this->post_rowlimit = " LIMIT $this->startat , $this->numrows ";
//print "JUST SET SESSION startat:	$this->startat <br>";			
		} 
		else{
			$this->startat = 0;
		}
		

		if(isset($this->post_rowlimit)){
		$_SESSION[$this->table_name . '_numrows'] = $this->numrows;
		$_SESSION[$this->table_name . '_startat'] = $this->startat;
		}
		
//$this->rowsmax = count($array_list);
			//paging calculations
		
			if($this->startat + $this->numrows < $this->rowsmax){
				$this->nextpagestart = $this->startat + $this->numrows;
			}
			else{
			$this->nextpagestart = $this->startat;
			}
		
		if($this->startat - $this->numrows > 0){
			$this->prevpagestart = $this->startat - $this->numrows;
			}
		else{
			$this->prevpagestart = 0;
		}
		$this->pageform = "<a href='" . $_SERVER['PHP_SELF'] . "?$this->startatvar=0&$this->numrowsvar=$this->numrows'>First</a>\n";
		$this->pageform .= "<a href='" . $_SERVER['PHP_SELF'] . "?$this->startatvar=$this->prevpagestart&$this->numrowsvar=$this->numrows'>Previous</a>\n";
		$this->pageform .= "<--   -->";
		$this->pageform .= "<a href='" . $_SERVER['PHP_SELF'] . "?$this->startatvar=$this->nextpagestart&$this->numrowsvar=$this->numrows'>Next</a>\n";
		//print "$this->prevpagestart : $this->nextpagestart : $this->rowsmax <br>";
		//end paging	
	
	}
	
	function make_pageform(){
			return $this->pageform;
	}
	
	function make_query_post_rowlimit(){
	return $this->post_rowlimit();
	
	}

	function make_multi_act_row($method = "get"){
		$none_entry[1]['keyvalue'] = '';
		$none_entry[1]['showvalue'] = '';
	
		$msrow .= "<table class='multi_act_row'>";
		$msrow .= "<form name='ms_form'  id='" . $this->table_name . "_ms_form' action='$this->actionpage' method='$method'>";
		$msrow .= "<thead><tr class='ms_head_class' >";
		foreach($this->fieldspec AS $col_name => $colspec){
			
			if($colspec[show] == 'E'){
				$msrow .= "<th>$col_name</th>";
			}
		} // end foreach fieldspec
		$msrow .= "</tr ></thead>\n";
		$msrow .= "<tbody><tr class='ms_row_class'>";
		foreach($this->fieldspec AS $col_name => $colspec){
			
			if($colspec[show] == 'E'){
				$msrow .= "<td>";
				$msrow .= $this->make_editbox($col_name, $col_name, '', '', $col_name, $none_entry);
				$msrow .= "</td>";
			}
		}	// end foreach fieldspec	
		
		$msrow .= "\n<td><input type='hidden' name='mode'>";
		$msrow .= "<input type='button' name='multiedit' value='Change ' onClick='doMultiChange()' >";
		$msrow .= "<input type='button' name='mutlidelete' value='Delete' onClick='doMultiDelete()' > ";
		$msrow .= "<input type='button' name='setmulti' value='Set' onClick='get_selections()' >";
				// Need to change the following name to something descriptive but unique and matches JS.
		$msrow .= "<input type='text' name='seltrans' id='seltrans'>";
		$msrow .= "</td></tr></tbody></form>\n";
	return $msrow;
	}
	
	function make_apply_all(){
		return "\n<input type='button' value='Select All' onClick='select_by_name()'><input type='button' value='Clear All' onClick='unselect_by_name()'>\n";
	
	}
	
	
}


class CF_Dpage_table extends CFtable{
	

	var $actionpage;

	
	// set this variable for order when re-ording this query with the headers
	var $ordervar = 'order';
	
	// New Methods
	function set_actionpage($pagename){
		$this->actionpage = $pagename;
	}

	
	function make_row_end($row_num){
		$endstring = "<td><a href='$this->actionpage?mode=Delete$this->url_keys_string$referstring'>Delete</a></td>";
		$endstring .= "</tr>\n";
		return $endstring;
	}	
}



class CF_EDpage_table extends CFtable{

	var $actionpage;		
	var $editpage;
	var $ordervar = 'order';
	var $allow_delete = true;
	var $allow_edit = true;
	
		
	// New Methods
	
	function set_allow($allowspec){
		if(stristr($allowspec,'d')){
			$this->allow_delete = true;
		}
		else{
			$this->allow_delete = false;
			}
		if(stristr($allowspec,'e')){
			$this->allow_edit = true;
		}		
		else{
			$this->allow_edit = false;
			}		
	}	
	
	
	function set_actionpage($pagename){
		$this->actionpage = $pagename;
	}	
	
	function set_editpage($pagename){
		$this->editpage = $pagename;
	}
	
		
	// Overrides and Extension mehods	
	function make_row_end($row_num){
		if($this->allow_delete){
			$endstring = "<td><a href='$this->actionpage?mode=Delete$this->url_keys_string$referstring'>Delete</a></td>";
			}
		if($this->allow_edit){
			$endstring .= "<td><a href='$this->editpage?mode=Edit$this->url_keys_string$referstring'>Edit</a></td>";
		}
		$endstring .= "</tr>\n";
		return $endstring;
	}	


	
}

class CF_InlineEDTable extends CF_EDpage_table {
	

	var $keys_hidden; // keys as hidden fields in form
	var $actionpage; // page form will go to for edit and delete actions
	var $ordervar = 'order';  // set this variable for order when re-ording this query with the headers
	
	
	// New Methods
	function set_actionpage($pagename){
		$this->actionpage = $pagename;
	}	
	
	function set_multiselect($value){
		$this->multiselect = $value;
	}
	// overrides
	
	function clear_keys_strings() { 
		//$this->url_keys_string = '';
		$this->keys_uid = '';
		$this->keys_hidden = '';
		parent::clear_keys_strings();
	}
	

	

	
	
	
	function make_rowval($value,$column){
		
		//$chgname = "chg_$column" . "()";
		
		$row_text .= "<td>";
		if($this->fieldspec[$column]['show'] == 'E'){
			$row_text .= $this->make_editbox($column,$column,$value,$chgname,$column);
		} else {
		$row_text .= "$value";
		}
		$row_text .= "</td>";
		return $row_text;
			
	}	

 /**
 * function to make start of row, making each row a form for editing
 * @param int $row_num This is the row number of the dataset
 * @param string $key_string This is the string of key values, defined by make_key_string function
 * @return string Row begining 
 */
	function make_row_start($row_num){
		$formname = $this->tablename . '_' . $this->keys_uid;
		$rowstart .= "<form action='$this->actionpage' name='$formname' method='GET'>";

		$rowstart .= $this->keys_hidden;
		
		if($this->row_status == 'even'){
			$this->row_status = 'odd';
			$rowstart .= "<tr class=\"even_row_color\">";			
		}
		else{
			$this->row_status = 'even';
			$rowstart .= "<tr class=\"odd_row_color\">";			
		}
		
		if($this->multiselect){
			$rowstart .= "<td>" . $this->make_multiselectCB() . "</td>";
		}		
		
		
		
		return $rowstart;
	}
	
	function make_row_end($row_num){
		if($this->allow_edit){
			$rowend .= "<td><input type='submit' name='mode' value='Save Row'></td>";
		}
		if($this->allow_delete){
			$rowend .= "<td><input type='submit' name='mode' value='Delete'></td>";
			}
		$rowend .= "</tr></form>\n";
		
		return $rowend;
	}
	
	// former position of make_multi_act_row
	
	

	
// sortorder and pagination was here -remove this note	
		
	
	
}// end Class CF_InlineEDTable

class CF_AJTable extends CF_InlineEDTable{
	
	var $oldvalvar = 'OV_';

	function make_rowval($value,$column){
		
		$chgname = "syncVal" . "('$column', '$this->keys_uid', '$column" . "_" . "$this->keys_uid')";
		
		$row_text .= "<td>";
		if($this->fieldspec[$column]['show'] == 'E'){
			$row_text .= $this->make_editbox($column,$column,$value,$chgname,$column . '_' . $this->keys_uid);
			$ov_name = $this->oldvalvar . $column;
			$row_text .= "<input type='hidden' name='$ov_name' value='$value' id='$ov_name" . "_$this->keys_uid'>";
		} else {
		$row_text .= "$value";
		}
		$row_text .= "</td>";
		return $row_text;
			
	}
	
}


